import json
import os
from datetime import datetime
from functools import wraps

import jwt
from flask import Blueprint, request, jsonify, g

from backend.model.scoring_model import score_essay_with_chatgpt
from backend.services.visualization_service import (
    get_bar_chart_data,
    get_score_trend_data,
    get_comparison_chart_data, get_radar_chart_data
)

# 配置信息
SECRET_KEY = 'your_secret_key'
TOKEN_EXPIRATION = 24 * 60 * 60  # 24小时过期


def decode_token(token):
    """
    解码JWT令牌
    """
    try:
        # 明确指定算法和验证选项
        payload = jwt.decode(
            token,
            SECRET_KEY,
            algorithms=['HS256'],
            options={
                'verify_exp': True,  # 验证过期时间
                'verify_iat': True,  # 验证签发时间
            }
        )
        return payload
    except jwt.ExpiredSignatureError:
        print("令牌已过期")
        return None
    except jwt.InvalidTokenError as e:
        print(f"无效的令牌: {str(e)}")
        return None
    except Exception as e:
        print(f"令牌解析错误: {str(e)}")
        return None


def token_required(f):
    """
    Token验证装饰器
    """

    @wraps(f)
    def decorated(*args, **kwargs):
        # 获取Authorization头
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            return jsonify({
                "code": 401,
                "message": "缺少Authorization头信息"
            }), 401

        # 验证Bearer格式
        parts = auth_header.split()
        if parts[0].lower() != 'bearer' or len(parts) != 2:
            return jsonify({
                "code": 401,
                "message": "无效的Authorization格式"
            }), 401

        token = parts[1]
        payload = decode_token(token)

        if payload is None:
            return jsonify({
                "code": 401,
                "message": "无效或过期的令牌"
            }), 401

        try:
            # 验证令牌中的必要信息
            if 'user_id' not in payload:
                return jsonify({
                    "code": 401,
                    "message": "令牌缺少用户信息"
                }), 401

            # 验证令牌是否过期
            exp_timestamp = payload.get('exp')
            if exp_timestamp is None:
                return jsonify({
                    "code": 401,
                    "message": "令牌缺少过期时间"
                }), 401

            current_timestamp = datetime.utcnow().timestamp()
            if current_timestamp > exp_timestamp:
                return jsonify({
                    "code": 401,
                    "message": "令牌已过期"
                }), 401

            # 将用户信息添加到请求上下文
            return f(payload['user_id'], *args, **kwargs)

        except Exception as e:
            return jsonify({
                "code": 401,
                "message": f"令牌验证失败: {str(e)}"
            }), 401

    return decorated


visualization_routes = Blueprint('visualization', __name__)

def success_response(message, data):
    return jsonify({"code": 200, "message": message, "data": data})

def error_response(message, code=400):
    return jsonify({"code": code, "message": message, "data": None}), code

# 【接口5.2.1】POST /visualization/radar  获取作文雷达图数据
@visualization_routes.route('/visualization/radar', methods=['POST'])
@token_required
def radar_chart(user_id):
    """
    获取作文雷达图数据
    :return: 返回作文评分的各项维度数据，用于雷达图展示
    """
    try:
        data = request.json
        essay_id = data.get("essay_id")
        version_id = data.get("version_id")

        if not essay_id or not version_id:
            return jsonify({"code": 400, "message": "缺少 essay_id 或 version_id 参数", "data": None}), 400

        result = get_radar_chart_data(user_id, essay_id, version_id)

        if not result or not result.get("dimensions"):
            return jsonify({"code": 400,"message": result.get("message", "版本 ID 不存在或数据缺失"),"data": None}), 400

        if result is None:
            return jsonify({"code": 500, "message": "生成雷达图数据失败", "data": None}), 500

        return jsonify({"code": 200, "message": "雷达图数据获取成功", "data": result}), 200

    except Exception as e:
        print(f"【接口5.2.1】获取雷达图数据失败: {e}")
        return jsonify({"code": 500, "message": "服务器内部错误", "data": None}), 500


# 【接口5.2.2】POST /visualization/bar  获取作文得分柱状图数据
@visualization_routes.route('/visualization/bar', methods=['POST'])
@token_required
def bar_chart(user_id):
    """
    获取作文得分柱状图数据
    :return: 返回多个作文的评分数据，用于柱状图展示
    """
    try:
        data = request.json
        essay_id = data.get("essay_id")  # 获取传入的 essay_id
        if not essay_id:
            return jsonify({"code": 400, "message": "缺少 essay_id 参数", "data": None}), 400

        result = get_bar_chart_data(user_id, essay_id)
        return jsonify({"code": 200, "message": "作文得分柱状图数据获取成功", "data": result}), 200

    except Exception as e:
        print(f"【接口5.2.2】获取作文得分柱状图数据失败: {e}")
        return jsonify({"code": 500, "message": "服务器内部错误", "data": None}), 500


# 【接口5.2.3】POST /visualization/trend  获取评分趋势数据
@visualization_routes.route('/visualization/trend', methods=['POST'])
@token_required
def score_trend(user_id):
    """
    获取评分趋势数据
    :return: 返回essay_id对应作文多个版本的评分趋势数据
    """
    try:
        data = request.json
        essay_id = data.get("essay_id")

        if not essay_id:
            return jsonify({"code": 400, "message": "缺少 essay_id 参数", "data": None}), 400

        result = get_score_trend_data(user_id, essay_id)
        return jsonify({"code": 200, "message": "评分趋势图数据获取成功", "data": result}), 200

    except Exception as e:
        print(f"【接口5.2.3】获取评分趋势数据失败: {e}")
        return jsonify({"code": 500, "message": "服务器内部错误", "data": None}), 500


# 【接口5.2.4】POST /visualization/comparison  获取评分维度对比数据
@visualization_routes.route('/visualization/comparison', methods=['POST'])
@token_required
def comparison_chart():
    """
    获取评分维度对比数据
    :return: 返回两篇作文的评分对比数据
    """
    try:
        data = request.json
        essay_id_1 = data.get("essay_id_1")
        essay_text_1 = data.get("essay_text_1")
        essay_id_2 = data.get("essay_id_2")
        essay_text_2 = data.get("essay_text_2")

        if not essay_id_1 or not essay_text_1 or not essay_id_2 or not essay_text_2:
            return jsonify({"code": 400, "message": "缺少 essay_id 或 essay_text 参数", "data": None}), 400

        result = get_comparison_chart_data(essay_id_1, essay_text_1, essay_id_2, essay_text_2)
        return jsonify({"code": 200, "message": "评分维度对比数据获取成功", "data": result}), 200

    except Exception as e:
        print(f"【接口5.2.4】获取评分维度对比数据失败: {e}")
        return jsonify({"code": 500, "message": "服务器内部错误", "data": None}), 500
